﻿<html>
 <head> 
  <title>Sciter中的内建的拖拽操作(Drag&Drop)</title> 
 </head> 
 <body> 
      <div class="post" id="post-89"> 
       <h1 class="storytitle">Sciter中的内建的拖拽操作(Drag&Drop)</h1> 
       <div class="storycontent"> 
        <p>据我所知，有两种不同的拖拽(drag-n-drop)机制:</p> 
        <ul> 
         <li><strong>全局拖拽</strong> 将对象从桌面上的一个窗口/程序拖拽到另一个窗口/程序上。在大多数情况下，除了额外的视觉效果，这个操作非常接近剪切板的'剪切-粘贴'操作。</li> 
         <li><strong>窗口局部拖拽</strong> 将对象在一个窗口/表单上拖拽。例如一些<a href="http://demo.script.aculo.us/shop">购物车</a>的实现。</li> 
        </ul> 
        <p>我已经为Sciter添加支持了后一种拖拽操作 – DOM元素的局部拖拽。详细内容见<a href="http://www.terrainformatica.com/wiki/doku.php?id=h-smile:drag-n-drop">这里</a>。</p> 
        <p>请考虑下的这个任务:</p> 
        <p>下面的两个select元素:</p> 
        <pre>&lt;select id=&quot;source&quot; size=&quot;5&quot;&gt;
  &lt;option&gt;一&lt;&lt;/option&gt;  
  &lt;option&gt;二&lt;&lt;/option&gt;  
  &lt;option&gt;三&lt;&lt;/option&gt;  
&lt;/select&gt;
&lt;select id=&quot;destination&quot; size=&quot;5&quot;&gt;&lt;/select&gt;</pre> 
        <p>如果我们要让它们支持将&lt;option&gt;元素从#source中拖拽到#destination，对于<em>htmlayout</em>或<em>the Sciter</em>(都是基于h-smile core)，可以写下以下代码: </p> 
        <pre>
   select#source &gt; option
   {
      dragging: only-move; /* 这里我们只能移动option元素 */ 
   }
   select#destination
   {
      accept-drag: selector( select#source &gt; option ); 
                  /* 我们只接受select#source中的option元素 */ 
      drop: append; 
                 /* option的顺序不是相关联的，新元素总是添加到最后 */
   }
</pre> 
        <p>这样就可以讲option元素从第一个&lt;select&gt;中拖拽到第二个。</p> 
        <p>但是一个好的UI设计的主要原则是什么 – “discoverability”? 当拖拽时应该有一个视觉线索: 用户什么时候以及哪里可以进行拖拽。下面的伪类将会帮助我们处理这种情况:</p> 
        <pre>
   option:moving /* 正在移动(拖拽)的option */
   {
      background:blue; color:white;
      opacity:0.5;
   }

   select:drop-target /* 当前激活的拖拽目标元素 */
   {
      background: yellow; 
      /* 在拖拽(D&amp;D)操作开始后，所有可用的拖拽目标元素将会高亮显示成黄色 */ 
   }

   select:drag-over /* 拖拽项当前悬停的拖拽目标元素*/
   {
      outline: 1px solid green; 
      /* 在当前鼠标位置的拖拽目标元素显示绿色的轮廓
          被拖拽元素可以放置在这个目标元素上 */ 
   }

</pre> 
        <p>以上是在我们的程序中添加拖拽功能所要做的所有事情。</p> 
        <p>哦, 还有一条: 如果需要进行双向拖拽，那我们要怎么做 – 从#destination拖拽到#source? 方法是一样的:</p> 
        <pre>

   select#destination &gt; option
   {
      dragging: only-move;  
   }

   select#source
   {
      accept-drag: selector( select#destination &gt; option ); 
      drop: append; 
   }
</pre> 
        <p>还有一小块内容: 若将声明了<code>drop:recycle</code>的元素作为拖拽目标，则放置在它声明的元素都将会被删除掉。</p> 
       </div> 
      </div>  
 </body>
</html>
